package vip.xiaonuo.invoice.core.util;

import vip.xiaonuo.invoice.modular.param.InvoiceRequestParam;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 数学计算工具类
 */
public class MathUtil {

    private static final Logger logger = LoggerFactory.getLogger(MathUtil.class);

    /**
     * 计算税额
     * @param includeTaxFlag 含税标志，1表示含税，0表示不含税（可为空，默认含税）
     * @param amount 金额
     * @param taxRate 税率（以小数形式传入，例如13%传入0.13）
     * @return 税额，保留两位小数的字符串
     */
    public static String calculateTax(String includeTaxFlag, String amount, String taxRate) {
        // 参数校验
        if (amount == null || taxRate == null) {
            throw new IllegalArgumentException("税额计算时有参数为空：金额或税率不能为空");
        }

        // 当含税标志为空时，默认使用含税（1表示含税）
        String effectiveIncludeTaxFlag = (includeTaxFlag == null || includeTaxFlag.trim().isEmpty())
                ? "1" : includeTaxFlag;

        // 检查含税标志是否合法
        if (!"0".equals(effectiveIncludeTaxFlag) && !"1".equals(effectiveIncludeTaxFlag)) {
            throw new IllegalArgumentException("含税标志必须为0或1");
        }

        try {
            // 将字符串转换为BigDecimal以确保精度
            BigDecimal amountBigDecimal = new BigDecimal(amount);
            BigDecimal taxRateBigDecimal = new BigDecimal(taxRate);

            // 直接使用传入的税率（已为小数形式）
            BigDecimal tax;

            if ("1".equals(effectiveIncludeTaxFlag)) {
                // 含税金额计算税额：税额 = 含税金额 * 税率 / (1 + 税率)
                BigDecimal denominator = BigDecimal.ONE.add(taxRateBigDecimal);
                tax = amountBigDecimal.multiply(taxRateBigDecimal).divide(denominator, 10, RoundingMode.HALF_UP);
            } else {
                // 不含税金额计算税额：税额 = 不含税金额 * 税率
                tax = amountBigDecimal.multiply(taxRateBigDecimal).setScale(10, RoundingMode.HALF_UP);
            }

            // 保留两位小数，使用HALF_UP模式（四舍五入）
            return tax.setScale(2, RoundingMode.HALF_UP).toString();

        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("金额或税率格式不正确，请输入有效的数字", e);
        }
    }

    /**
     * 计算所有商品的价税合计总金额
     * @param includeTaxFlag 含税标志，1表示含税，0表示不含税（可为空，默认含税）
     * @param itemList 商品明细列表
     * @return 价税合计总金额，保留两位小数的BigDecimal；计算失败时返回null
     */
    public static BigDecimal calculateTotalAmountWithTax(String includeTaxFlag, List<InvoiceRequestParam.Item> itemList) {
        try {
            // 参数校验
            if (itemList == null || itemList.isEmpty()) {
                logger.error("商品明细列表为空，无法计算价税合计总金额");
                return null;
            }

            // 当含税标志为空时，默认使用含税（1表示含税）
            String effectiveIncludeTaxFlag = (includeTaxFlag == null || includeTaxFlag.trim().isEmpty())
                    ? "1" : includeTaxFlag;

            // 检查含税标志是否合法
            if (!"0".equals(effectiveIncludeTaxFlag) && !"1".equals(effectiveIncludeTaxFlag)) {
                logger.error("含税标志格式不正确，必须为0或1，当前值：{}", effectiveIncludeTaxFlag);
                return null;
            }

            // 初始化总价税合计金额
            BigDecimal totalAmountWithTax = BigDecimal.ZERO;

            for (InvoiceRequestParam.Item item : itemList) {
                // 校验商品信息
                if (item.getAmount() == null || item.getTaxRate() == null) {
                    logger.error("商品明细中金额或税率为空，商品名称：{}", item.getProductName());
                    return null;
                }

                try {
                    BigDecimal amount = new BigDecimal(item.getAmount());
                    BigDecimal taxRate = new BigDecimal(item.getTaxRate());

                    // 计算当前商品的价税合计金额
                    BigDecimal itemAmountWithTax;
                    if ("1".equals(effectiveIncludeTaxFlag)) {
                        // 若金额已含税，则直接使用
                        itemAmountWithTax = amount;
                    } else {
                        // 若金额不含税，则计算价税合计：不含税金额 * (1 + 税率)
                        itemAmountWithTax = amount.multiply(BigDecimal.ONE.add(taxRate));
                    }

                    // 累加总价税合计金额
                    totalAmountWithTax = totalAmountWithTax.add(itemAmountWithTax);
                } catch (NumberFormatException e) {
                    logger.error("商品明细中金额或税率格式不正确，商品名称：{}, 金额：{}, 税率：{}", 
                            item.getProductName(), item.getAmount(), item.getTaxRate(), e);
                    return null;
                }
            }

            // 保留两位小数，使用HALF_UP模式（四舍五入）
            return totalAmountWithTax.setScale(2, RoundingMode.HALF_UP);

        } catch (Exception e) {
            logger.error("计算价税合计总金额时发生异常", e);
            return null;
        }
    }

    /**
     * 根据含税标志计算不含税金额
     * @param includeTaxFlag 含税标志（1:含税,0:不含税）
     * @param itemList 商品明细列表
     * @return 不含税金额，保留两位小数的BigDecimal；计算失败时返回null
     */
    public static BigDecimal calculateWithoutTaxAmount(String includeTaxFlag, List<InvoiceRequestParam.Item> itemList) {
        try {
            // 参数校验 - 商品列表是必须的
            if (itemList == null || itemList.isEmpty()) {
                logger.error("商品明细列表为空，无法计算不含税金额");
                return null;
            }

            // 当含税标志为空时，默认使用含税（1表示含税）
            String effectiveIncludeTaxFlag = (includeTaxFlag == null || includeTaxFlag.trim().isEmpty())
                    ? "1" : includeTaxFlag;

            // 检查含税标志是否合法
            if (!"0".equals(effectiveIncludeTaxFlag) && !"1".equals(effectiveIncludeTaxFlag)) {
                logger.error("含税标志格式不正确，必须为0或1，当前值：{}", effectiveIncludeTaxFlag);
                return null;
            }

            BigDecimal withoutTaxAmount = BigDecimal.ZERO;
            
            for (InvoiceRequestParam.Item item : itemList) {
                if (item.getAmount() == null) {
                    logger.error("商品明细中金额为空，商品名称：{}", item.getProductName());
                    return null;
                }

                try {
                    BigDecimal amount = new BigDecimal(item.getAmount());
                    
                    if ("1".equals(effectiveIncludeTaxFlag)) {
                        // 含税标志时，需要计算不含税金额：不含税金额 = 含税金额 / (1 + 税率)
                        if (item.getTaxRate() == null) {
                            logger.error("商品明细中税率为空，商品名称：{}", item.getProductName());
                            return null;
                        }
                        BigDecimal taxRate = new BigDecimal(item.getTaxRate());
                        BigDecimal itemWithoutTaxAmount = amount.divide(
                                BigDecimal.ONE.add(taxRate), 10, RoundingMode.HALF_UP);
                        withoutTaxAmount = withoutTaxAmount.add(itemWithoutTaxAmount);
                    } else {
                        // 不含税标志时，直接使用商品金额
                        withoutTaxAmount = withoutTaxAmount.add(amount);
                    }
                } catch (NumberFormatException e) {
                    logger.error("商品明细中金额或税率格式不正确，商品名称：{}, 金额：{}, 税率：{}", 
                            item.getProductName(), item.getAmount(), item.getTaxRate(), e);
                    return null;
                }
            }
            
            // 保留两位小数，使用HALF_UP模式（四舍五入）
            withoutTaxAmount = withoutTaxAmount.setScale(2, RoundingMode.HALF_UP);

            return withoutTaxAmount;

        } catch (Exception e) {
            logger.error("计算不含税金额时发生异常", e);
            return null;
        }
    }
    
    /**
     * 计算所有商品的不含税总金额
     * @param itemList 商品明细列表
     * @return 不含税总金额，保留两位小数的BigDecimal；计算失败时返回null
     */
    public static BigDecimal calculateTotalAmountWithoutTax(List<InvoiceRequestParam.Item> itemList) {
        try {
            // 参数校验
            if (itemList == null || itemList.isEmpty()) {
                logger.error("商品明细列表为空，无法计算不含税总金额");
                return null;
            }

            // 初始化不含税总金额
            BigDecimal totalAmountWithoutTax = BigDecimal.ZERO;

            for (InvoiceRequestParam.Item item : itemList) {
                // 校验商品信息
                if (item.getAmount() == null || item.getTaxRate() == null) {
                    logger.error("商品明细中金额或税率为空，商品名称：{}", item.getProductName());
                    return null;
                }

                try {
                    BigDecimal amount = new BigDecimal(item.getAmount());
                    BigDecimal taxRate = new BigDecimal(item.getTaxRate());
                    
                    // 由于这里是计算不含税金额，我们假设传入的amount是含税金额
                    // 不含税金额 = 含税金额 / (1 + 税率)
                    BigDecimal itemAmountWithoutTax = amount.divide(
                            BigDecimal.ONE.add(taxRate), 10, RoundingMode.HALF_UP);
                    
                    // 累加不含税总金额
                    totalAmountWithoutTax = totalAmountWithoutTax.add(itemAmountWithoutTax);
                } catch (Exception e) {
                    logger.error("商品明细不含税金额计算失败，商品名称：{}, 金额：{}, 税率：{}", 
                            item.getProductName(), item.getAmount(), item.getTaxRate(), e);
                    return null;
                }
            }

            // 保留两位小数，使用HALF_UP模式（四舍五入）
            return totalAmountWithoutTax.setScale(2, RoundingMode.HALF_UP);

        } catch (Exception e) {
            logger.error("计算不含税总金额时发生异常", e);
            return null;
        }
    }

    /**
     * 计算所有商品的总税额
     * @param includeTaxFlag 含税标志，1表示含税，0表示不含税（可为空，默认含税）
     * @param itemList 商品明细列表
     * @return 总税额，保留两位小数的BigDecimal；计算失败时返回null
     */
    public static BigDecimal calculateTotalTaxAmount(String includeTaxFlag, List<InvoiceRequestParam.Item> itemList) {
        try {
            // 参数校验
            if (itemList == null || itemList.isEmpty()) {
                logger.error("商品明细列表为空，无法计算总税额");
                return null;
            }

            // 当含税标志为空时，默认使用含税（1表示含税）
            String effectiveIncludeTaxFlag = (includeTaxFlag == null || includeTaxFlag.trim().isEmpty())
                    ? "1" : includeTaxFlag;

            // 检查含税标志是否合法
            if (!"0".equals(effectiveIncludeTaxFlag) && !"1".equals(effectiveIncludeTaxFlag)) {
                logger.error("含税标志格式不正确，必须为0或1，当前值：{}", effectiveIncludeTaxFlag);
                return null;
            }

            // 初始化总税额
            BigDecimal totalTaxAmount = BigDecimal.ZERO;

            for (InvoiceRequestParam.Item item : itemList) {
                // 校验商品信息
                if (item.getAmount() == null || item.getTaxRate() == null) {
                    logger.error("商品明细中金额或税率为空，商品名称：{}", item.getProductName());
                    return null;
                }

                try {
                    BigDecimal amount = new BigDecimal(item.getAmount());
                    BigDecimal taxRate = new BigDecimal(item.getTaxRate());
                    
                    // 计算当前商品的税额
                    BigDecimal itemTaxAmount;
                    if ("1".equals(effectiveIncludeTaxFlag)) {
                        // 含税金额计算税额：税额 = 含税金额 * 税率 / (1 + 税率)
                        BigDecimal denominator = BigDecimal.ONE.add(taxRate);
                        itemTaxAmount = amount.multiply(taxRate).divide(denominator, 10, RoundingMode.HALF_UP);
                    } else {
                        // 不含税金额计算税额：税额 = 不含税金额 * 税率
                        itemTaxAmount = amount.multiply(taxRate).setScale(10, RoundingMode.HALF_UP);
                    }

                    // 累加总税额
                    totalTaxAmount = totalTaxAmount.add(itemTaxAmount);
                } catch (NumberFormatException e) {
                    logger.error("商品明细中金额或税率格式不正确，商品名称：{}, 金额：{}, 税率：{}", 
                            item.getProductName(), item.getAmount(), item.getTaxRate(), e);
                    return null;
                }
            }

            // 保留两位小数，使用HALF_UP模式（四舍五入）
            return totalTaxAmount.setScale(2, RoundingMode.HALF_UP);

        } catch (Exception e) {
            logger.error("计算总税额时发生异常", e);
            return null;
        }
    }
    
    /**
     * 检查商品明细中所有商品的税率是否一致
     * @param itemList 商品明细列表
     * @return 一致的税率；如果税率不一致，抛出异常
     */
    public static BigDecimal checkConsistentTaxRate(List<InvoiceRequestParam.Item> itemList) {
        if (itemList == null || itemList.isEmpty()) {
            throw new IllegalArgumentException("商品明细列表为空，无法检查税率一致性");
        }
        
        BigDecimal standardTaxRate = null;
        
        for (InvoiceRequestParam.Item item : itemList) {
            if (item.getTaxRate() == null) {
                throw new IllegalArgumentException("商品明细中税率为空，商品名称：" + item.getProductName());
            }
            
            try {
                BigDecimal currentTaxRate = new BigDecimal(item.getTaxRate());
                
                if (standardTaxRate == null) {
                    // 设置第一个商品的税率为标准税率
                    standardTaxRate = currentTaxRate;
                } else if (!standardTaxRate.equals(currentTaxRate)) {
                    // 如果当前商品的税率与标准税率不一致，抛出异常
                    throw new IllegalArgumentException("商品明细中税率不一致，商品：" + item.getProductName() + 
                            " 的税率为：" + currentTaxRate + "，而标准税率为：" + standardTaxRate);
                }
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("商品明细中税率格式不正确，商品名称：" + item.getProductName() + 
                        "，税率值：" + item.getTaxRate());
            }
        }
        
        return standardTaxRate;
    }
    
    /**
     * 格式化金额，保留两位小数
     * @param amount 金额字符串
     * @return 格式化后的金额字符串
     */
    public static String formatAmount(String amount) {
        if (amount == null) {
            throw new IllegalArgumentException("金额不能为空");
        }

        try {
            return new BigDecimal(amount).setScale(2, RoundingMode.HALF_UP).toString();
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("金额格式不正确，请输入有效的数字", e);
        }
    }
}
